package edu.stanford.bmir.protege.web.server.transform.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.jxpath.JXPathContext;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLObjectProperty;

import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.AssociativeRelationship;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.CustomConceptAttribute;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.CustomNote;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.HierarchicalRelationship;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.ISO25964Interchange;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.PreferredTerm;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.SimpleNonPreferredTerm;
import edu.stanford.bmir.protege.web.server.transform.service.org.iso25964.ThesaurusConceptStruct;
import edu.stanford.bmir.protege.web.shared.transform.ClassBean;

public class XmlOwl extends OwlUtil {
	
	private JXPathContext context;

	public XmlOwl(String path, Map<String, String> pros, IRI projectIRI)
			throws Exception {
		super(path, pros, projectIRI);
		context = getXmlContent();
	}

	@Override
	protected void createProperty(String key, String value) {
		
		String pValue = pros.get( key );
		if ( StringWord.OBJECTPROPERTY.equals( pValue ) ) {
			createObjectproperty( key );
		}
		if ( StringWord.DATAPROPERTY.equals( pValue ) ) {
			createDataproperty( key );
		}
		
	}

	@Override
	protected List<String> getProperty(String path) {
		
		List<String> pros = new ArrayList<String>();
		pros.add( StringWord.SIMPLENONPREFERREDTERM );
		for ( Iterator<?> iter = context.iterate( "/groupRelationshipOrTopLevelRelationshipOrAssociativeRelationship/role"); iter.hasNext(); )
        {
			 	String new_name = (String) iter.next();
			 	if ( !pros.contains( new_name ) ) {
			 		pros.add( new_name );
			 	}
        }
		for ( Iterator<?> iter = context.iterate( "/thesaurus/thesaurusConcept/customConceptAttribute"); iter.hasNext(); )
        {
			CustomConceptAttribute cca = (CustomConceptAttribute) iter.next();
			if ( !pros.contains( cca.getCustomAttributeType() ) ) {
				pros.add( cca.getCustomAttributeType() );
			}
        }
		
		Iterator iter = context.iterate( "/thesaurus/thesaurusConcept/customNote");
		if ( iter.hasNext() ) {
			if ( !pros.contains( StringWord.CUSTOMNOTE ) ) {
				pros.add( StringWord.CUSTOMNOTE );
			}
		}
		
		return pros;
	}

	@Override
	protected void createClasses() {
		
		List<ClassBean> clst = getClassBeanlst();
		
		for ( ClassBean bean : clst ) {
			
			String name = bean.getName();
			
			OWLClass cls = null;
			
			Map<String,ArrayList> pros = bean.getProperty();
			
			List<String> parentPros = getProName(StringWord.SUBCLASSOF);
			
			if ( parentPros.isEmpty() ) {
				
				cls = createClass ( name,null );
				
			} else {
				
				List<String> pNames = pros.get( parentPros.get(0) );
				if ( pNames != null && !pNames.isEmpty() ) {
					
					for ( String pName : pNames ) {
						
						cls =	createClass ( name,pName );
					}
					
				} else {
					cls = createClass ( name,null );
				}
			}
			//设置lable
			List<String> llst = bean.getoNames();
			
			if ( llst != null ) {
				for ( String oName : llst ) {
					
					setLabel( cls.asOWLClass().getIRI() , oName);
					
				}
			}
			//处理Rt
			List<String> rPros = getProName(StringWord.RELATEDTERM);
			
			if ( !rPros.isEmpty() ) {
				
				for ( String rpName : rPros ) {
					
					List<String> sNames = pros.get( rpName );
					
					if ( sNames == null ) {
						continue;
					}
					
					for ( String sName : sNames ) {
						OWLClass nose = factory.getOWLClass( createIRI( sName ) );
						OWLObjectProperty obp = createObjectproperty( name+"_relatedTerm_"+sName , cls, nose);
						
						addObjectproperty( obp,sName,cls );
						
					}
					
				}
				
			}
			
			/*//处理simpleNonPreferedTerm
			String pValue = this.pros.get( StringWord.SIMPLENONPREFERREDTERM );
			if ( pValue != null && pValue != "" ) {
				
				List<String> sNames = pros.get( StringWord.SIMPLENONPREFERREDTERM );
				
				if ( pValue.equals(StringWord.LABEL) ) {
					
					for ( String sName : sNames  ) {
						setLabel( cls.asOWLClass().getIRI() , sName);
					}
					
				}
			
			}*/
			
			/**
			 * 处理等价类
			 */
			List<String> ePros = getProName(StringWord.EQUIVALENTCLASS);
			
			if ( !ePros.isEmpty() ) {
				
				for ( String eName : ePros ) {
					
					List<String> sNames = pros.get( eName );
					
					if ( sNames == null ) {
						continue;
					}
					
					for ( String sName : sNames ) {
						addEquivalentClass( cls , sName);
					}
					
				}
				
			}
			/**
			 * 处理label
			 */
			List<String> lPros = getProName(StringWord.LABEL);
			
			if ( !lPros.isEmpty() ) {
				
				for ( String eName : lPros ) {
					
					List<String> sNames = pros.get( eName );
					
					if ( sNames == null ) {
						continue;
					}
					
					for ( String sName : sNames ) {
						setLabel( cls.asOWLClass().getIRI() , sName);
					}
					
				}
				
			}
			
			//添加数据属性
			List<String> dataPros = getProName(StringWord.DATAPROPERTY);
			
			if ( !dataPros.isEmpty() ) {
				
				for ( String dpName : dataPros ) {
					
					List<String> sNames = pros.get( dpName );
					
					if ( sNames == null ) {
						continue;
					}
					
					for ( String sName : sNames ) {
						addDataproperty( dpName,sName,cls );
						
					}
					
				}
				
			}
			//添加对象属性
			List<String> objectPros = getProName(StringWord.OBJECTPROPERTY);
			if ( !objectPros.isEmpty() ) {
				for ( String opName : objectPros ) {
					List<String> sNames = pros.get( opName );
					if ( sNames == null ) {
						continue;
					}
					for ( String sName : sNames ) {
						addObjectproperty( opName,sName,cls );
					}
				}
			}
		}
	}
	
	private JXPathContext getXmlContent () throws Exception {
		JAXBContext instance = JAXBContext.newInstance("edu.stanford.bmir.protege.web.server.transform.service.org.iso25964");
		Unmarshaller unmarshaller = instance.createUnmarshaller();
		File file  = new File(getPath());
		ISO25964Interchange result = (ISO25964Interchange) unmarshaller.unmarshal(file);
		
		JXPathContext context = JXPathContext.newContext( result );
		
		return context;
	}
	
	public List<ClassBean> getClassBeanlst () {
		
		List<ClassBean> classlst = new ArrayList<ClassBean>();
		
		ISO25964Interchange c = (ISO25964Interchange) context.getValue( "." );
		
		List<ThesaurusConceptStruct> lst = c.getThesaurus().getThesaurusConcept();
		
		Long start = new Date().getTime();
		
		for ( ThesaurusConceptStruct tcs : lst ) {
			
			ClassBean bean = new ClassBean();
			
			HashMap<String, ArrayList> pros = new HashMap<String,ArrayList>();
			
			//优选词
			List<PreferredTerm> plst = tcs.getPreferredTerm();
			List<String> oNames = new ArrayList<String>();
			//通过优选词未词条赋值
			if ( plst.size() > 1 ) {
				for ( PreferredTerm pTerm : plst ) {
					String lang = pTerm.getLexicalValue().getLang();
					String name = pTerm.getLexicalValue().getValue();
					if ( "en".equals( lang ) ) {
						bean.setName( name );
					} else {
						oNames.add( name );
					}
				}
				bean.setoNames( oNames );
			} else {
				bean.setName( plst.get(0).getLexicalValue().getValue() );
			}
			
			//添加属性
			List<SimpleNonPreferredTerm> splst = tcs.getSimpleNonPreferredTerm();
			
			if ( !splst.isEmpty() ) {
				ArrayList<String> spValues = new ArrayList<String>();
				for ( SimpleNonPreferredTerm snpt : splst ) {
					String value = snpt.getLexicalValue().getValue();
					spValues.add( value );
				}
				pros.put( StringWord.SIMPLENONPREFERREDTERM,spValues );
			}
			//添加自定义属性
			List<CustomConceptAttribute> cclst = tcs.getCustomConceptAttribute();
			
			if ( !cclst.isEmpty() ) {
			
				for ( CustomConceptAttribute cca : cclst ) {
					
					String value = cca.getLexicalValue().getValue();
					String key = cca.getCustomAttributeType();
					if ( pros.containsKey( key ) ) {
						pros.get( key ).add( value );
					} else {
						ArrayList<String> ccaValues = new ArrayList<String>();
						ccaValues.add( value );
						pros.put( key , ccaValues);
					}
				}
				
			}
			//添加自定义属性
			List<CustomNote> ctlst = tcs.getCustomNote();
			
			if ( !ctlst.isEmpty() ) {
				
				ArrayList<String> cnlst = new ArrayList<String>();
				for ( CustomNote cn : ctlst ) {
					
					cnlst.add( cn.getLexicalValue().getValue() );
					
				}
				pros.put( "customNote" , cnlst);
			}
			
			
			//层级关系
			 for ( Iterator<?> iter2 = context.iterate( "/groupRelationshipOrTopLevelRelationshipOrAssociativeRelationship[hasHierRelConcept=\""+tcs.getIdentifier()+"\"]"); iter2.hasNext(); )
             {
				 	HierarchicalRelationship new_name = (HierarchicalRelationship) iter2.next();
				 	String key = new_name.getRole();
				 	String value = new_name.getIsHierRelConcept();
				 	
				 	String cName = (String) context.getValue( "/thesaurus/thesaurusConcept[identifier=\""+value+"\"]/preferredTerm/lexicalValue/value" );
				 	if ( cName == null || cName == "" ) {
				 		continue;
				 	}
				 	if ( pros.containsKey( key ) ) {
				 		pros.get( key ).add( cName );
				 	} else {
				 		ArrayList<String> values = new ArrayList<String>();
				 		values.add( cName );
				 		pros.put( key , values);
				 	}
             }
			 //关联关系
			 for ( Iterator<?> iter1 = context.iterate( "/groupRelationshipOrTopLevelRelationshipOrAssociativeRelationship[hasRelatedConcept=\""+tcs.getIdentifier()+"\"]"); iter1.hasNext(); )
             {
				 AssociativeRelationship new_name = (AssociativeRelationship) iter1.next();
				 	String key = new_name.getRole();
				 	String value = new_name.getIsRelatedConcept();
				 	
				 	String cName = (String) context.getValue( "/thesaurus/thesaurusConcept[identifier=\""+value+"\"]/preferredTerm/lexicalValue/value" );
				 	if ( cName == null || cName == "" ) {
				 		continue;
				 	}
				 	if ( pros.containsKey( key ) ) {
				 		pros.get( key ).add( cName );
				 	} else {
				 		ArrayList<String> values = new ArrayList<String>();
				 		values.add( cName );
				 		pros.put( key , values);
				 	}
             }
			 
			 bean.setProperty(pros);
			 
			 classlst.add( bean );
			 
		}
		Long end = new Date().getTime();
		
		System.out.println( end-start );
		
		return classlst;
		
	}

}
